#ifndef CNC_BASE_CNC_KERNEL_H
#define CNC_BASE_CNC_KERNEL_H

#include "opmodeid.h"
#include <coopsched.h>   // base/kernel
#include <coopmode.h>    // base/kernel
// provided interfaces
#include <cooptask.h>    // base/kernel
#include <kernelsetup.h> // base/kernel

namespace cnc {

	namespace base {

		struct CNCKernel :
			public KernelSetup,
			public CooperativeTask
		{
			typedef CooperativeScheduler<OperationModeID, CooperativeTask, CooperativeMode> CooperativeScheduler_;
			CooperativeScheduler_ scheduler_;
		protected:
			CNCKernel()
			{}
		public:
			KernelSetup *getKernelSetup()
			{
				return static_cast<KernelSetup *>(this);
			}
			CooperativeTask *getCooperativeTask()
			{
				return static_cast<CooperativeTask *>(this);
			}
		private: // Kernel Setup
			virtual void addTask(CooperativeTask *backgroundTask)
			{
				scheduler_.addTask(backgroundTask);
			}
			virtual void addMode(OperationModeID modeID, CooperativeMode *operationMode)
			{
				if (modeID != OPMODE_END)
					scheduler_.addMode(modeID, operationMode);
			}
			virtual void selectMode(OperationModeID modeID)
			{
				if (modeID != OPMODE_END)
					scheduler_.selectMode(modeID);
			}
			virtual OperationModeID getMode()
			{
				return scheduler_.getMode();
			}
		private: // Task Control
			virtual bool start()
			{
				return scheduler_.start();
			}
			virtual bool execute()
			{
				return scheduler_.execute();
			}
			virtual bool stop()
			{
				return scheduler_.stop();
			}
		public:
			static CNCKernel &instance()
			{
				static CNCKernel object;
				return object;
			}
		};

	} // namespace base

} // namespace cnc

#endif
